package com.wulian.gateway.controller;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import com.wulian.common.entity.AppResultMoudel;
import com.wulian.common.vo.UserVO;
import com.wulian.gateway.feign.UserService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.wulian.common.constants.UserConstant;
import com.wulian.common.controller.BaseController;
import com.wulian.common.dto.UserInfo;
import com.wulian.common.entity.CarSysUser;
import com.wulian.common.suport.RibbonFilterContextHolder;
import com.wulian.common.util.JSONUtil;
import com.wulian.common.vo.ResultMoudel;

import lombok.extern.slf4j.Slf4j;

/**
 * @author scol
 */
@RestController
@RequestMapping("/login")
@Slf4j
public class LoginController extends BaseController<UserInfo> {
	private static final long TOKEN_EXPIRE_TIME = 60 * 60 * 24 * 30 * 12;

	@Autowired
	StringRedisTemplate redisTemplate;

	@Autowired
	private UserService userService;
	/**
	 * 
	 * @Title: generateToken
	 * @Description: TODO(token生成)
	 * @param @return
	 *            设定文件
	 * @return String 返回类型
	 * @throws @author
	 *             马志豪
	 * @date 2019年9月11日 上午10:38:25
	 * @version V1.0
	 */
	private String generateToken() {
		return UUID.randomUUID().toString().replaceAll("-", "");
	}

	/**
	 * 
	 * @Title: saveRedis
	 * @Description: TODO(用户信息存入redis)
	 * @param @param
	 *            userId
	 * @param @param
	 *            token
	 * @param @param
	 *            jsonUser 设定文件
	 * @return void 返回类型
	 * @throws @author
	 *             马志豪
	 * @date 2019年9月11日 上午10:41:16
	 * @version V1.0
	 */
	private String saveRedis(String userId,String type, String token, String jsonUser) {
		log.info("《----------------------------登录成功删除之前的token-------------------------------》");
		String lodToken = redisTemplate.opsForValue().get(UserConstant.USER_ID_TOKEN_PREFIEX + userId+type);
		if (null != lodToken) {
			redisTemplate.delete(UserConstant.USER_TOKEN_PREFIEX + lodToken);
		}
		redisTemplate.delete(UserConstant.USER_ID_TOKEN_PREFIEX + userId+type);
		log.info("《----------------------------添加新的token-------------------------------》");
		redisTemplate.opsForValue().set(UserConstant.USER_TOKEN_PREFIEX + token, jsonUser, TOKEN_EXPIRE_TIME,
				TimeUnit.SECONDS);
		redisTemplate.opsForValue().set(UserConstant.USER_ID_TOKEN_PREFIEX + userId+type, token, TOKEN_EXPIRE_TIME,
				TimeUnit.SECONDS);
		// 根据userId查询redis是否有登陆信息
		String redisToken = redisTemplate.opsForValue().get(UserConstant.USER_ID_TOKEN_PREFIEX + userId+type);
		if (StringUtils.isNotEmpty(redisToken)) {
			String userInfoJson = redisTemplate.opsForValue().get(UserConstant.USER_TOKEN_PREFIEX + redisToken);
			if (StringUtils.isNotEmpty(userInfoJson)) {
				UserInfo user = JSONUtil.fromJSON(userInfoJson, UserInfo.class);
				if("_dut".equals(type)){
					if ((String.valueOf(user.getDtuPeopleBingInfoDto().getId())+type).equals(userId+type)
							) {
						redisTemplate.opsForValue().set(UserConstant.USER_TOKEN_PREFIEX + redisToken, jsonUser,
								TOKEN_EXPIRE_TIME, TimeUnit.SECONDS);
						return token;
					}
				}/*else if("_car".equals(type)){
					if ((String.valueOf(user.getCarSysUser().getUserId())+type).equals(userId+type) ) {
						redisTemplate.opsForValue().set(UserConstant.USER_TOKEN_PREFIEX + redisToken, jsonUser, TOKEN_EXPIRE_TIME, TimeUnit.SECONDS);
						return token;
					}
				}*/else{
					if ((String.valueOf(user.getSysUser().getUserId())+type).equals(userId+type)
							) {
						redisTemplate.opsForValue().set(UserConstant.USER_TOKEN_PREFIEX + redisToken, jsonUser,
								TOKEN_EXPIRE_TIME, TimeUnit.SECONDS);
						return token;
					}
				}

			}
		}
		return token;
	}

	/**
	 * 将用户信息缓存到当前Context中,供后续业务访问
	 *
	 * @param userInfo
	 */
	protected void handleUserInfo(Object userInfo) {
		RibbonFilterContextHolder.getCurrentContext().add("userInfo", JSONUtil.toJSON(userInfo));
	}

	public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
		Map<String, Object> map = new HashMap<String, Object>();
		Class<?> clazz = obj.getClass();
		for (Field field : clazz.getDeclaredFields()) {
			field.setAccessible(true);
			String fieldName = field.getName();
			Object value = field.get(obj);
			map.put(fieldName, value);
		}
		return map;
	}


	/*@RequestMapping(value = "/login", method = RequestMethod.POST)
	public ResultMoudel<Object> carLogin(@RequestBody CarSysUser carSysUser) {
		String token = generateToken();
		// 用户信息存入redis
		token = saveRedis(String.valueOf(1),"_pc", token, "");
		Map<String, String> map = new HashMap<>();
		map.put("token", token);
		map.put("name", "小马");
		return new ResultMoudel<>(ResultMoudel.SUCCESS_FLAG, map);
	}*/

	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public ResultMoudel<Object> login(@RequestBody UserVO userVo) {
		String token = generateToken();
		if (null != userVo) {
			// 获取用户信息,不为空时即为token验证通过默认登录
			UserInfo currentUser = getCurrentUser();
			if (null != currentUser) {
				return new ResultMoudel<Object>("success", "默认登录成功");
			}
			// 当用户信息为空时,则需要校验用户名/密码的正确性再登录
			if (StringUtils.isBlank(userVo.getUsername())) {
				return new ResultMoudel<Object>("error", "用户名不可为空");
			}
			if (StringUtils.isBlank(userVo.getPassword())) {
				return new ResultMoudel<Object>("error", "密码不可为空");
			}
			// feign调用验证登录
			ResultMoudel<Object> resultMoudel = userService.login(userVo);
			String resultFlag = resultMoudel.getResultFlag();
			if ("success".equals(resultFlag)) {
				UserInfo userInfo = JSONUtil.fromJSON(resultMoudel.getBody().toString(), UserInfo.class);
				String userJson = JSONUtil.toJSON(userInfo);
				log.info("用户信息为 userJson:{}", userJson);
				// 用户信息存入redis
				token = saveRedis(String.valueOf(userInfo.getSysUser().getUserId()),"_pc", token, userJson);
				Map<String, String> map = new HashMap<>();
				map.put("token", token);
				map.put("name", userInfo.getSysUser().getName());
				// 追加返回值，用户状态，用户ID，部门ID
				map.put("status", userInfo.getSysUser().getStatus().toString());
				map.put("userid", userInfo.getSysUser().getUserId().toString());
				map.put("deptid", userInfo.getSysUser().getDeptId().toString());
				String isadmin_auth = String.valueOf(userInfo.getSysUser().getIsadminAuth());
				map.put("isadmin_auth", isadmin_auth);
				// set人员信息
				// userService.setUserInfo();
				return new ResultMoudel<>(ResultMoudel.SUCCESS_FLAG, map);
			} else {
				return resultMoudel;
			}
		} else {
			// 默认为是没有token进行登录
			return new ResultMoudel<Object>("error", "用户名和密码不可为空");
		}
	}

	/**
	 * 功能描述: <br>
	 * 〈手机端登录：手机端登录的时候登录和pc走的不是一套逻辑〉
	 *
	 * @Param:
	 * @Return:
	 * @Author: caifulin
	 * @Date: 2020/5/6
	 */
	@RequestMapping(value = "/loginApp", method = RequestMethod.POST)
	@ApiOperation("手机端登录：手机端登录的时候登录和pc走的不是一套逻辑")
	public AppResultMoudel<Object> loginApp(@RequestBody UserVO userVo) {
		try {
			String token = generateToken();
			if (null != userVo) {
				// 获取用户信息,不为空时即为token验证通过默认登录
				UserInfo currentUser = getCurrentUser();
				if (null != currentUser) {

					return new AppResultMoudel().success(null, "默认登录成功");
				}
				// 当用户信息为空时,则需要校验用户名/密码的正确性再登录
				if (StringUtils.isBlank(userVo.getUsername()) && StringUtils.isBlank(userVo.getPhone())) {
					return new AppResultMoudel().error(null, "用户名不可为空");
				}
				if (!StringUtils.isBlank(userVo.getUsername())) {
					if (StringUtils.isBlank(userVo.getPassword())) {
						return new AppResultMoudel().error(null, "密码不可为空");
					}
				}
				// feign调用验证登录
				AppResultMoudel resultMoudel = userService.loginApp(userVo);
				Integer code = resultMoudel.getCode();

				if (code.equals(0)) {
					UserInfo userInfo = JSONUtil.fromJSON(resultMoudel.getBody().toString(), UserInfo.class);
					String userJson = JSONUtil.toJSON(userInfo);
					log.info("用户信息为 userJson:{}", userJson);
					// 删除之前的该用户的token
					// redisTemplate.delete(UserConstant.USER_ID_TOKEN_PREFIEX+userInfo.getSysUser().getUserId());
					// 用户信息存入redis
					token = saveRedis(String.valueOf(userInfo.getSysUser().getUserId()),"_app", token, userJson); // 通过type来区分是PC还是APP登录
					Map<String, Object> map = new HashMap<>();
					map.put("token", token);
					map.put("name", userInfo.getSysUser().getName());
					map.put("username", userInfo.getSysUser().getUsername());
					map.put("projectId", userInfo.getSysUser().getProjectId());
					map.put("projectName", userInfo.getSysUser().getProjectName());
					map.put("phone", userInfo.getSysUser().getPhone());
					map.put("authority", userInfo.getSysUser().getAuthority());
					map.put("idCard",userInfo.getSysUser().getIdCard());
					map.put("leader",userInfo.getSysUser().getLeader());
					// Add 2021/05/13 追加deptid、status与userid
					map.put("deptid",userInfo.getSysUser().getDeptId());
					map.put("status",userInfo.getSysUser().getStatus());
					map.put("userid",userInfo.getSysUser().getUserId());
					map.put("isadmin_auth",userInfo.getSysUser().getIsadminAuth());
					return new AppResultMoudel().success(map, "登录成功");
				} else {
					return resultMoudel;
				}

			} else {
				// 默认为是没有token进行登录
				return new AppResultMoudel().error(null, "用户名和密码不可为空");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new AppResultMoudel().error(null, "系统异常");
		}
	}
}
